home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / PROGRAM / UCRASM25.ARJ / GETC.ASM < prev    next >
Assembly Source File  |  1991-10-12  |  7KB  |  281 lines

  1. ;
  2. ;
  3. ;
  4. StdGrp        group    stdlib, stdData
  5. ;
  6. StdData        segment    para public 'sldata'
  7. ;
  8. ; InpVector- Points at the current keyboard input routine.
  9. ;
  10. GetcAdrs    dd    sl_GetcStdIn
  11. GetcStkIndx    dw    0
  12. GetcStk        dd    16 dup (sl_GetcStdIn)
  13. GSIsize        =    $-GetcStk
  14. ;
  15. ; CharBuf- Used to hold character when reading from standard input device.
  16. ;
  17. CharBuf        db    ?
  18. ;
  19. ;
  20. ; LastChar- Used by BIOS keyboard routine to split non-ASCII keypresses
  21. ; into two separate calls.
  22. ;
  23. LastChar    dw    101h
  24. ;
  25. ; LastWasCR gets set to 1 when we read a CR.  If the char read when LastWasCR
  26. ; is one is a LF, this code eats the CR.
  27. ;
  28. LastWasCR    db    1        ;Assume at start last char was CR.
  29. ;
  30. StdData        ends
  31. ;
  32. stdlib        segment    para public 'slcode'
  33.         assume    cs:StdGrp,ds:nothing
  34. ;
  35. ; Keyboard input routines
  36. ;
  37. ; Released to the public domain
  38. ; Created by: Randall Hyde
  39. ; Date: 7/90
  40. ; Updates:
  41. ;
  42. ;    8/11/90-    Modifications to use DOS 3fh call and handle eof
  43. ;    2/20/91-    Modified routines to eat LFs following CRs after
  44. ;            call to DOS getc routine.
  45. ;    3/6/91-        Modified code to use DOS raw mode for standard
  46. ;            input rather than cooked mode.  Added SetInBIOS,
  47. ;            SetInStd, and SetInRaw routines.
  48. ;
  49. ;
  50. cr        equ    0dh
  51. lf        equ    0ah
  52. CtrlZ        equ    1ah
  53. ;
  54. ;
  55. ;
  56. ;
  57.         public    sl_Getc
  58. sl_Getc        proc    far
  59.         jmp    dword ptr StdGrp:GetcAdrs
  60. sl_Getc        endp
  61. ;
  62. ;
  63. ; SetInAdrs- Stores ES:DI into InpVector which sets the new keyboard vector.
  64. ;
  65.         public    sl_SetInAdrs
  66. sl_SetInAdrs    proc    far
  67.         mov    word ptr stdgrp:GetcAdrs, di
  68.         mov    word ptr stdgrp:GetcAdrs+2, es
  69.         ret
  70. sl_SetInAdrs    endp
  71. ;
  72. ;
  73. ; GetInAdrs-    Returns the address of the current output routine in ES:DI.
  74. ;
  75.         public    sl_GetInAdrs
  76. sl_GetInAdrs    proc    far
  77.         les    di, dword ptr stdgrp:GetcAdrs
  78.         ret
  79. sl_GetInAdrs    endp
  80. ;
  81. ;
  82. ;
  83. ; PushInAdrs-    Pushes the current input address onto the input stack
  84. ;        and then stores the address in es:di into the input address
  85. ;        pointer.  Returns carry clear if no problems.  Returns carry
  86. ;        set if there is an address stack overflow.  Does NOT modify
  87. ;        anything if the stack is full.
  88. ;
  89.         public    sl_PushInAdrs
  90. sl_PushInAdrs    proc    far
  91.         push    ax
  92.         push    di
  93.         cmp    stdgrp:GetcStkIndx, GSIsize
  94.         jae    BadPush
  95.         mov    di, stdgrp:GetcStkIndx
  96.         add    stdgrp:GetcStkIndx, 4
  97.         mov    ax, word ptr stdgrp:GetcAdrs
  98.         mov    word ptr stdgrp:GetcStk[di], ax
  99.         mov    ax, word ptr stdgrp:GetcAdrs+2
  100.         mov    word ptr stdgrp:GetcStk+2[di], ax
  101.         pop    di
  102.         mov    word ptr stdgrp:GetcAdrs, di
  103.         mov    word ptr stdgrp:GetcAdrs+2, es
  104.         pop    ax
  105.         clc
  106.         ret
  107. ;
  108. BadPush:    pop    di
  109.         pop    ax
  110.         stc
  111.         ret
  112. sl_PushInAdrs    endp
  113. ;
  114. ;
  115. ; PopInAdrs-    Pops an input address off of the stack and stores it into
  116. ;        the GetcAdrs variable.
  117. ;
  118.         public    sl_PopInAdrs
  119. sl_PopInAdrs    proc    far
  120.         push    ax
  121.         mov    di, stdgrp:GetcStkIndx
  122.         sub    di, 4
  123.         jns    GoodPop
  124. ;
  125. ; If this guy just went negative, set it to zero and push the address
  126. ; of the stdout routine onto the stack.
  127. ;
  128.         xor    di, di
  129.         mov    word ptr stdgrp:GetcStk, offset stdgrp:sl_GetcStdIn
  130.         mov    word ptr stdgrp:GetcStk+2, seg stdgrp:sl_GetcStdIn
  131. ;
  132. GoodPop:    mov    stdgrp:GetcStkIndx, di
  133.         mov    es, word ptr GetcAdrs+2
  134.         mov    ax, word ptr stdgrp:GetcStk+2[di]
  135.         mov    word ptr stdgrp:GetcAdrs+2, ax
  136.         mov    ax, word ptr stdgrp:GetcStk[di]
  137.         xchg    word ptr stdgrp:GetcAdrs, ax
  138.         mov    di, ax
  139.         pop    ax
  140.         ret
  141. sl_PopInAdrs    endp
  142. ;
  143. ;
  144. ;
  145. ; SetInBIOS- Points the input pointer at the GetcBIOS routine.
  146. ;
  147.         public    sl_SetInBIOS
  148. sl_SetInBIOS    proc    far
  149.         mov    word ptr StdGrp:GetcAdrs, offset stdgrp:sl_GetcBIOS
  150.         mov    word ptr StdGrp:GetcAdrs+2, stdgrp
  151.         ret
  152. sl_SetInBIOS    endp
  153. ;
  154. ;
  155. ;
  156. ; SetInStd- Points the input pointer at the GetcStdIn routine.
  157. ;
  158.         public    sl_SetInStd
  159. sl_SetInStd    proc    far
  160.         mov    word ptr StdGrp:GetcAdrs, offset stdgrp:sl_GetcStdIn
  161.         mov    word ptr StdGrp:GetcAdrs+2, stdgrp
  162.         ret
  163. sl_SetInStd    endp
  164. ;
  165. ;
  166. ;
  167. ;
  168. ;
  169. ;
  170. ;
  171. ; GetcBIOS-     Reads a character from the keyboard using the BIOS routines.
  172. ;        Behaves just like DOS call insofar as it returns a zero if
  173. ;        the user presses a non-ASCII key and then returns the scan
  174. ;        code as the next keypress.  Returns 1 in AH signifying that
  175. ;        we haven't reached EOF.
  176. ;
  177.         public    sl_GetcBIOS
  178. sl_GetcBIOS    proc    far
  179.         cmp    byte ptr stdgrp:LastChar, 0
  180.         jnz    GetNewChar
  181.         mov    ah, 1
  182.         mov    al, byte ptr stdgrp:LastChar+1
  183.         mov    byte ptr stdgrp:LastChar, al
  184.         mov    stdgrp:LastWasCR, 0            ;BIOS doesn't convert
  185.         ret                    ; CR-> CR/LF.
  186. ;
  187. GetNewChar:    mov    ah, 0
  188.         int    16h
  189.         mov    stdgrp:LastChar, ax
  190.         mov    ah, 1            ;Never EOF.
  191.         mov    stdgrp:LastWasCR, 0
  192.         ret
  193. sl_GetcBIOS    endp
  194. ;
  195. ;
  196. ;
  197. ; GetcStdIn-     Reads a character from DOS' standard input.
  198. ;
  199. ; On return: ah=0 if eof, 1 if not eof.  AL=character.
  200. ;
  201. ; Modification 2/20/91:
  202. ;
  203. ;    Modified this code to eat any line feeds which immediately follow a
  204. ;    CR on the standard input.
  205. ;
  206. ;        3/8/91:
  207. ;
  208. ;    Modified this code to treat reading data from a file and from a
  209. ;    device as two different operations.  This removed some performance
  210. ;    problems and helped make the code a little "safer".
  211. ;
  212.         public    sl_GetcStdIn
  213.         assume    ds:StdGrp
  214. sl_GetcStdIn    proc    far
  215.         push    bx
  216.         push    cx
  217.         push    dx
  218.         push    ds
  219. ;
  220.         mov    ax, 4400h        ;IOCTL read call
  221.         xor    bx, bx            ;Use std in handle.
  222.         int    21h
  223.         test    dl, 80h            ;See if file (0) or device (1).
  224.         jz    GetcAgain
  225. ;
  226.         test    dl, 40h            ;Check for EOF on device.
  227.         jz    DeviceEOF
  228. ;
  229. ; At this point we're reading a character from a device.  Simply call the
  230. ; DOS character input routine so we can avoid buffering and other nasty
  231. ; problems.  Note we have to handle EOF ourselves here.  DOS, however,
  232. ; handles ctrl-C.
  233. ;
  234.         mov    ah, 8
  235.         int    21h
  236.         mov    ah, 1
  237.         cmp    al, CtrlZ
  238.         jne    GoodRead
  239. DeviceEOF:    mov    ah, 0
  240.         jmp    Short GoodRead
  241. ;
  242. ;
  243. ; If we're reading from a file (rather than a device like the keyboard),
  244. ; drop down here to read the character using standard buffered I/O.
  245. ; Make sure to strip off LFs following CRs (since LFs typically follow CRs
  246. ; in a file).
  247. ;
  248. GetcAgain:    mov    ah, 3fh
  249.         mov    dx, cs
  250.         mov    ds, dx
  251.         mov    CharBuf, 0        ;Don't let LF trip us up.
  252.         lea    dx, stdgrp:CharBuf    ;Put char into CharBuf.
  253.         mov    cx, 1            ;Read one character.
  254.         mov    bx, 0            ;StdIn file handle
  255.         int    21h
  256.         jc    BadRead
  257.         mov    ah, al            ;ah=0 if eof, 1 if not eof.
  258.         mov    al, CharBuf        ;Get char if not eof.
  259.         cmp    al, LF            ;Was last char a line feed?
  260.         jne    NotLF
  261.         cmp    LastWasCR, 0
  262.         mov    LastWasCR, 0
  263.         jne    GetcAgain
  264. ;
  265. NotLF:        mov    LastWasCR, 0
  266.         cmp    al, CR
  267.         jne    GoodRead
  268.         mov    LastWasCR,1
  269. ;
  270. GoodRead:    clc
  271. BadRead:    pop    ds
  272.         pop    dx
  273.         pop    cx
  274.         pop    bx
  275.         ret
  276. sl_GetcStdIn    endp
  277. ;
  278. ;
  279. stdlib        ends
  280.         end
  281.